//
//  File.swift
//  
//
//  Created by czi on 2023/12/8.
//

import Foundation
public protocol Executor {
    func execute(_ request: URLRequest) async throws -> (Data, HTTPURLResponse)
    
    @discardableResult
    func execute(_ request: URLRequest) -> URLSessionDataTask
    
    @discardableResult
    func execute(_ request: URLRequest, completionHandler: @escaping @Sendable (Data?, HTTPURLResponse?, Error?) -> Void) -> URLSessionDataTask
}

extension URLSession: Executor {
    public func execute(_ request: URLRequest) async throws -> (Data, HTTPURLResponse) {
        try await data(for: request) as! (Data, HTTPURLResponse)
    }
    
    @discardableResult
    public func execute(_ request: URLRequest, completionHandler: @escaping @Sendable (Data?, HTTPURLResponse?, Error?) -> Void) -> URLSessionDataTask {
        let task = dataTask(with: request) { data, response, error in
            completionHandler(data, response as? HTTPURLResponse, error)
        }
        task.resume()
        return task
    }
    
    @discardableResult
    public func execute(_ request: URLRequest) -> URLSessionDataTask {
        let task = dataTask(with: request)
        task.resume()
        return task
    }
}
